package com.shop.cereshop.commons.service.ocr;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.shop.cereshop.commons.config.TXCOSConfig;
import com.shop.cereshop.commons.domain.im.tx.req.ocr.BizLicenseOCRReq;
import com.shop.cereshop.commons.domain.im.tx.req.ocr.IdCardOCRReq;
import com.shop.cereshop.commons.domain.im.tx.resp.ocr.BizLicenseOCRResp;
import com.shop.cereshop.commons.domain.im.tx.resp.ocr.IdCardOCRResp;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.ocr.v20181119.OcrClient;
import com.tencentcloudapi.ocr.v20181119.models.BizLicenseOCRRequest;
import com.tencentcloudapi.ocr.v20181119.models.BizLicenseOCRResponse;
import com.tencentcloudapi.ocr.v20181119.models.IDCardOCRRequest;
import com.tencentcloudapi.ocr.v20181119.models.IDCardOCRResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * 腾讯云OCR服务
 * 提供各种OCR识别功能
 */
@Slf4j
@Service
public class TencentOCRService {

    @Resource
    private TXCOSConfig tencentCOSConfig;

    /**
     * 营业执照识别
     * 参考文档：https://cloud.tencent.com/document/product/866/36215
     *
     * @param req 营业执照识别请求参数
     * @return 营业执照识别结果
     */
    public BizLicenseOCRResp bizLicenseOCR(BizLicenseOCRReq req) {
        try {
            // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey
            Credential cred = new Credential(tencentCOSConfig.getSecretId(), tencentCOSConfig.getSecretKey());

            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("ocr.tencentcloudapi.com");
            // 设置连接超时时间（毫秒）
            httpProfile.setConnTimeout(30000);
            // 设置读取超时时间（毫秒）
            httpProfile.setReadTimeout(30000);
            // 设置写入超时时间（毫秒）
            httpProfile.setWriteTimeout(30000);

            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);

            // 实例化要请求产品的client对象,clientProfile是可选的
            OcrClient client = new OcrClient(cred, "ap-beijing", clientProfile);

            // 实例化一个请求对象,每个接口都会对应一个request对象
            BizLicenseOCRRequest request = new BizLicenseOCRRequest();

            // 设置请求参数
            if (req.getImageBase64() != null && !req.getImageBase64().isEmpty()) {
                request.setImageBase64(req.getImageBase64());
            }
            if (req.getImageUrl() != null && !req.getImageUrl().isEmpty()) {
                request.setImageUrl(req.getImageUrl());
            }
            if (req.getEnableCopyWarn() != null) {
                request.setEnableCopyWarn(req.getEnableCopyWarn());
            }
            if (req.getEnablePeriodComplete() != null) {
                request.setEnablePeriodComplete(req.getEnablePeriodComplete());
            }
            if (req.getEnableBusinessCertificate() != null) {
                request.setEnableBusinessCertificate(req.getEnableBusinessCertificate());
            }

            // 返回的resp是一个BizLicenseOCRResponse的实例，与请求对象对应
            BizLicenseOCRResponse response = client.BizLicenseOCR(request);

            // 将腾讯云SDK的响应转换为JSON字符串，然后转换为我们的实体类
            String jsonResponse = com.tencentcloudapi.common.AbstractModel.toJsonString(response);
            log.info("腾讯云OCR响应: {}", jsonResponse);

            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.readValue(jsonResponse, BizLicenseOCRResp.class);

        } catch (TencentCloudSDKException e) {
            log.error("腾讯云OCR SDK异常: {}", e.toString(), e);
            BizLicenseOCRResp errorResp = new BizLicenseOCRResp();
            errorResp.setRequestId("ERROR");
            errorResp.setErrorMsg(e.getMessage());
            return errorResp;
        } catch (Exception e) {
            log.error("营业执照识别异常: {}", e.getMessage(), e);
            BizLicenseOCRResp errorResp = new BizLicenseOCRResp();
            errorResp.setRequestId("ERROR");
            errorResp.setErrorMsg(e.getMessage());
            return errorResp;
        }

    }

    /**
     * 营业执照识别 - 通过图片URL
     *
     * @param imageUrl 图片URL地址
     * @return 营业执照识别结果
     */
    public BizLicenseOCRResp bizLicenseOCRByUrl(String imageUrl) {
        BizLicenseOCRReq req = new BizLicenseOCRReq();
        req.setImageUrl(imageUrl);
        return bizLicenseOCR(req);
    }

    /**
     * 营业执照识别 - 通过图片Base64
     *
     * @param imageBase64 图片Base64编码
     * @return 营业执照识别结果
     */
    public BizLicenseOCRResp bizLicenseOCRByBase64(String imageBase64) {
        BizLicenseOCRReq req = new BizLicenseOCRReq();
        req.setImageBase64(imageBase64);
        return bizLicenseOCR(req);
    }

    /**
     * 身份证识别
     * 参考文档：https://cloud.tencent.com/document/product/866/33524
     *
     * @param req 身份证识别请求参数
     * @return 身份证识别结果
     */
    public IdCardOCRResp idCardOCR(IdCardOCRReq req) {
        try {
            // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey
            Credential cred = new Credential(tencentCOSConfig.getSecretId(), tencentCOSConfig.getSecretKey());

            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("ocr.tencentcloudapi.com");
            // 设置连接超时时间（毫秒）
            httpProfile.setConnTimeout(30000);
            // 设置读取超时时间（毫秒）
            httpProfile.setReadTimeout(30000);
            // 设置写入超时时间（毫秒）
            httpProfile.setWriteTimeout(30000);

            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);

            // 实例化要请求产品的client对象,clientProfile是可选的
            OcrClient client = new OcrClient(cred, "ap-beijing", clientProfile);

            // 实例化一个请求对象,每个接口都会对应一个request对象
            IDCardOCRRequest request = new IDCardOCRRequest();

            // 设置请求参数
            if (req.getImageBase64() != null && !req.getImageBase64().isEmpty()) {
                request.setImageBase64(req.getImageBase64());
            }
            if (req.getImageUrl() != null && !req.getImageUrl().isEmpty()) {
                request.setImageUrl(req.getImageUrl());
            }
            if (req.getCardSide() != null && !req.getCardSide().isEmpty()) {
                request.setCardSide(req.getCardSide());
            }
            if (req.getConfig() != null && !req.getConfig().isEmpty()) {
                request.setConfig(req.getConfig());
            }

            // 返回的resp是一个IDCardOCRResponse的实例，与请求对象对应
            IDCardOCRResponse response = client.IDCardOCR(request);

            // 将腾讯云SDK的响应转换为JSON字符串，然后转换为我们的实体类
            String jsonResponse = com.tencentcloudapi.common.AbstractModel.toJsonString(response);
            log.info("腾讯云身份证OCR响应: {}", jsonResponse);

            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.readValue(jsonResponse, IdCardOCRResp.class);

        } catch (TencentCloudSDKException e) {
            log.error("腾讯云身份证OCR SDK异常: {}", e.toString(), e);
            IdCardOCRResp errorResp = new IdCardOCRResp();
            errorResp.setRequestId("ERROR" );
            errorResp.setErrorMsg(e.getMessage());
            return errorResp;
        } catch (Exception e) {
            log.error("身份证识别异常: {}", e.getMessage(), e);
            IdCardOCRResp errorResp = new IdCardOCRResp();
            errorResp.setRequestId("ERROR" );
            errorResp.setErrorMsg(e.getMessage());
            return errorResp;
        }
    }

    /**
     * 身份证识别 - 通过图片URL
     *
     * @param imageUrl 图片URL地址
     * @param cardSide 身份证面类型 FRONT-人像面 BACK-国徽面
     * @return 身份证识别结果
     */
    public IdCardOCRResp idCardOCRByUrl(String imageUrl, String cardSide) {
        IdCardOCRReq req = new IdCardOCRReq();
        req.setImageUrl(imageUrl);
        req.setCardSide(cardSide);
        return idCardOCR(req);
    }

    /**
     * 身份证识别 - 通过图片Base64
     *
     * @param imageBase64 图片Base64编码
     * @param cardSide 身份证面类型 FRONT-人像面 BACK-国徽面
     * @return 身份证识别结果
     */
    public IdCardOCRResp idCardOCRByBase64(String imageBase64, String cardSide) {
        IdCardOCRReq req = new IdCardOCRReq();
        req.setImageBase64(imageBase64);
        req.setCardSide(cardSide);
        return idCardOCR(req);
    }

    /**
     * 身份证双面识别 - 通过图片URL
     *
     * @param frontImageUrl 身份证正面（人像面）图片URL
     * @param backImageUrl 身份证反面（国徽面）图片URL
     * @return 身份证识别结果Map，包含正面和反面信息
     */
    public Map<String, IdCardOCRResp> idCardOCRBothSidesByUrl(String frontImageUrl, String backImageUrl) {
        Map<String, IdCardOCRResp> result = new HashMap<>();

        // 识别正面
        IdCardOCRResp frontResult = idCardOCRByUrl(frontImageUrl, "FRONT");
        result.put("front", frontResult);

        // 识别反面
        IdCardOCRResp backResult = idCardOCRByUrl(backImageUrl, "BACK");
        result.put("back", backResult);

        return result;
    }
}
